//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V0.1.1
#include "oled_driver.h"
#include <string.h>

static WHT_OLED_Info_t WHT_OLED_Info;
static uint8_t OLED_TRx_Buf[OLED_BUFF_SIZE];


/**********************驱动初始化配置*********************/
#ifdef OLED_Soft_I2C
static WHT_Soft_I2C_Cache_t wht_cache;

static void WHT_OLED_Driver_Init(void)
{
    if (WHT_Soft_I2C_BUS1_Init() != 0)
    {
        /* 总线初始化失败 */
        return;
    }
    wht_cache.Cmd_Count = 1;
}
#else
static SemaphoreHandle_t Tx_xSemaphore;//二值信号量句柄
static SemaphoreHandle_t Rx_xSemaphore;

static WHT_I2C_Cache_t wht_cache;

static void WHT_Tx_Idle_IT_Callback(void);
static void WHT_Rx_Idle_IT_Callback(void);
static void WHT_OLED_Driver_Init(void)
{
    if (WHT_I2C_BUS1_Init() != 0)
    {
        /* 总线初始化失败 */
        return;
    }
    wht_cache.Addr_7Bit = 0x50;
    wht_cache.Cmd_Count = 1;
    wht_cache.Read_Finish_IT_CB = WHT_Rx_Idle_IT_Callback;
    wht_cache.Write_Finish_IT_CB = WHT_Tx_Idle_IT_Callback;

    Tx_xSemaphore = xSemaphoreCreateBinary();
    Rx_xSemaphore = xSemaphoreCreateBinary();
}
#endif // OLED_Soft_I2C
/**********************驱动初始化配置*********************/


/************************** start read & write *******************************/
#ifdef OLED_Soft_I2C
static void WHT_OLED_Driver_Write(WHT_OLED_Addr_enum addr_7bit, uint8_t* const input_buf, uint32_t count)
{
    while (WHT_Soft_I2C_BUS1->Mutex == I2C_Lock)//等待互斥锁成功打开
    {
        vTaskDelay(1);
    }
    wht_cache.Addr_7Bit = addr_7bit;
    wht_cache.Dir = Soft_I2C_Write;
    //wht_cache.Cmd[0] = cmd;
    wht_cache.Buffer = input_buf;
    wht_cache.Buffer_Count = count;

    WHT_Soft_I2C_BUS_OPS.Read_Write(WHT_Soft_I2C_BUS1, &wht_cache);
}
static void WHT_OLED_Driver_Read(WHT_OLED_Addr_enum addr_7bit, uint8_t* const output_buf, uint32_t count)
{
    while (WHT_Soft_I2C_BUS1->Mutex == I2C_Lock)//等待互斥锁成功打开
    {
        vTaskDelay(1);
    }
    wht_cache.Addr_7Bit = addr_7bit;
    wht_cache.Dir = Soft_I2C_Read;
    //wht_cache.Cmd[0] = cmd;
    wht_cache.Buffer = output_buf;
    wht_cache.Buffer_Count = count;

    WHT_Soft_I2C_BUS_OPS.Read_Write(WHT_Soft_I2C_BUS1, &wht_cache);
}
static uint8_t WHT_OLED_Driver_Scan_I2C_Slave_Count(void)
{
    return WHT_Soft_I2C_BUS_OPS.Scan_Mount_Count(WHT_Soft_I2C_BUS1);
}
#else
/*发送空闲中断回调函数*/
static void WHT_Tx_Idle_IT_Callback(void)
{
    BaseType_t xHigherPriorityTaskWoken;

    xSemaphoreGiveFromISR(Tx_xSemaphore, &xHigherPriorityTaskWoken);//释放信号量
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
/*接收空闲中断回调函数*/
static void WHT_Rx_Idle_IT_Callback(void)
{
    BaseType_t xHigherPriorityTaskWoken;

    xSemaphoreGiveFromISR(Rx_xSemaphore, &xHigherPriorityTaskWoken);//释放信号量
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
static void WHT_OLED_Driver_Write(WHT_OLED_Addr_enum addr, uint8_t* const input_buf, uint32_t count)
{
    while (WHT_I2C_BUS1->Mutex == I2C_Lock)//等待互斥锁成功打开
    {
        vTaskDelay(1);
    }
    wht_cache.Addr_7Bit = addr;
    wht_cache.Dir = I2C_Write;
    //wht_cache.Cmd[0] = cmd;
    wht_cache.Buffer = input_buf;
    wht_cache.Buffer_Count = count;

    TickType_t Tick_Count = count * 9 * 1000  / WHT_I2C_BUS1->Config.I2C_Rate_Hz / portTICK_RATE_MS;//单位ms/Tick

    if (Tick_Count)
        WHT_I2C_BUS_OPS.Read_Write_DMA(WHT_I2C_BUS1, &wht_cache);
    else
         WHT_I2C_BUS_OPS.Read_Write_IT(WHT_I2C_BUS1, &wht_cache);
        
    if (WHT_I2C_BUS1->Mutex == I2C_Unlock)//传输结束
    {
        /*用户可以加入判断是否有错误相关代码*/
    }
    else
        xSemaphoreTake(Tx_xSemaphore, portMAX_DELAY);//等待信号量
}
static void WHT_OLED_Driver_Read(WHT_OLED_Addr_enum addr, uint8_t* const output_buf, uint32_t count)
{
    while (WHT_I2C_BUS1->Mutex == I2C_Lock)//等待互斥锁成功打开
    {
        vTaskDelay(1);
    }
    wht_cache.Addr_7Bit = addr;
    wht_cache.Dir = I2C_Read;
    //wht_cache.Cmd[0] = cmd;
    wht_cache.Buffer = output_buf;
    wht_cache.Buffer_Count = count;

    TickType_t Tick_Count = count * 9 * 1000  / WHT_I2C_BUS1->Config.I2C_Rate_Hz / portTICK_RATE_MS;//单位ms/Tick

    if (Tick_Count)
        WHT_I2C_BUS_OPS.Read_Write_DMA(WHT_I2C_BUS1, &wht_cache);
    else
        WHT_I2C_BUS_OPS.Read_Write_IT(WHT_I2C_BUS1, &wht_cache);

    if (WHT_I2C_BUS1->Mutex == I2C_Unlock)//传输结束
    {
        /*用户可以加入判断是否有错误相关代码*/
    }
    else
        xSemaphoreTake(Rx_xSemaphore, portMAX_DELAY);//等待信号量

}
static uint8_t WHT_OLED_Driver_Scan_I2C_Slave_Count(void)
{
    return WHT_I2C_BUS_OPS.Scan_Mount_Count(WHT_I2C_BUS1);
}
#endif // OLED_Soft_I2C
/************************** end read & write ********************************/




/**************************控制***********************/
static WHT_OLED_Addressing_Mode_enum WHT_OLED_Addressing_Mode = Horizontal_Addressing_Mode;//OLED寻址模式
/*设置内存地址寻址模式*/
static void WHT_OLED_Driver_Set_Addressing_Mode(WHT_OLED_Addressing_Mode_enum mode)
{
    if (WHT_OLED_Addressing_Mode == mode)
        return;
    else
    {
        wht_cache.Cmd_Count = 3;
        wht_cache.Cmd[0] = OLED_Write_Cmd;
        wht_cache.Cmd[1] = OLED_Set_Addressing_Mode;
        wht_cache.Cmd[2] = mode;
        WHT_OLED_Driver_Write(OLED_7Bit_Addr0, NULL, 0);

        wht_cache.Cmd_Count = 1;
        WHT_OLED_Addressing_Mode = mode;
    }
}
/*从休眠中唤醒*/
static void WHT_OLED_Driver_Display_ON(void)
{
    wht_cache.Cmd_Count = 3;

    wht_cache.Cmd[0] = OLED_Write_Cmd;
    wht_cache.Cmd[1] = 0x8D;            //设置电荷泵
    wht_cache.Cmd[2] = 0x14;            //开启电荷泵
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, NULL, 0);

    wht_cache.Cmd_Count = 2;
    wht_cache.Cmd[1] = 0xAF;            //OLED唤醒
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, NULL, 0);

    wht_cache.Cmd_Count = 1;
}
/*进入休眠模式 OLED功耗不到10uA*/
static void WHT_OLED_Driver_Display_OFF(void)
{
    wht_cache.Cmd_Count = 3;

    wht_cache.Cmd[0] = OLED_Write_Cmd;
    wht_cache.Cmd[1] = 0x8D;            //设置电荷泵
    wht_cache.Cmd[2] = 0x10;            //关闭电荷泵
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, NULL, 0);

    wht_cache.Cmd_Count = 2;
    wht_cache.Cmd[1] = 0xAE;            //OLED休眠
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, NULL, 0);

    wht_cache.Cmd_Count = 1;
}
/*设置对比度亮度*/
static void WHT_OLED_Driver_Set_LM(uint8_t lm_value)
{
    if (WHT_OLED_Info.LM == lm_value)
        return;
    else
    {
        wht_cache.Cmd_Count = 3;
        wht_cache.Cmd[0] = OLED_Write_Cmd;
        wht_cache.Cmd[1] = OLED_Set_LM;
        wht_cache.Cmd[2] = lm_value;
        WHT_OLED_Driver_Write(OLED_7Bit_Addr0, NULL, 0);
        wht_cache.Cmd_Count = 1;
    }
    WHT_OLED_Info.LM = lm_value;
}
/*设置字体行和列位置*/
static uint8_t WHT_OLED_Driver_Set_Font_Pos(uint16_t row, uint16_t col)
{
    uint8_t Max_Display_Font_Row_Number;//屏幕最大显示字体行数
	uint8_t Idle_Row_Number;            //屏幕空闲行数
	
	Max_Display_Font_Row_Number = OLED_SCREEN_High / WHT_OLED_Info.Font->Height;
	Idle_Row_Number = OLED_SCREEN_High % WHT_OLED_Info.Font->Height;
	WHT_OLED_Info.New_Col = col >= OLED_SCREEN_Wide ? 0 : col;
	WHT_OLED_Info.New_Page = row % Max_Display_Font_Row_Number + Idle_Row_Number;//屏幕上方字体空闲区域
	return Idle_Row_Number;
}
/**************************控制***********************/


/************************填充*************************/
/*设置页寻址模式下的光标位置*/
static void WHT_OLED_Driver_Set_Page_Window(uint8_t s_page, uint8_t s_col)
{
    WHT_OLED_Driver_Set_Addressing_Mode(Page_Addressing_Mode);
    
    wht_cache.Cmd_Count = 2;

    wht_cache.Cmd[0] = OLED_Write_Cmd;

    wht_cache.Cmd[1] = 0xB0 + s_page;
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, NULL, 0);

    wht_cache.Cmd[1] = 0x10 + (s_col >> 4);
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, NULL, 0);

    wht_cache.Cmd[1] = 0x00 + (s_col & 0x0f);
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, NULL, 0);

    wht_cache.Cmd_Count = 1;

    WHT_OLED_Driver_Set_Addressing_Mode(Horizontal_Addressing_Mode);
}
/*起始位置与结束位置,水平模式或垂直模式下有效*/
static void WHT_OLED_Driver_Set_Window(uint8_t s_page, uint8_t s_col, uint8_t e_page, uint8_t e_col)
{
    WHT_OLED_Driver_Set_Addressing_Mode(Horizontal_Addressing_Mode);

    wht_cache.Cmd_Count = 4;

    wht_cache.Cmd[0] = OLED_Write_Cmd;
    wht_cache.Cmd[1] = OLED_Set_Col;
    wht_cache.Cmd[2] = s_col;
    wht_cache.Cmd[3] = e_col;
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, NULL, 0);//设置列位置范围

    wht_cache.Cmd[1] = OLED_Set_Page;
    wht_cache.Cmd[2] = s_page;
    wht_cache.Cmd[3] = e_page;
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, NULL, 0);//设置页位置范围

    wht_cache.Cmd_Count = 1;
}
/*指定区域内填充数据*/
static void WHT_OLED_Driver_Fill_Buf(uint8_t s_page, uint8_t s_col, uint8_t e_page, uint8_t e_col, const uint8_t* intput_buf, uint32_t count)
{
	WHT_OLED_Driver_Set_Window(s_page, s_col, e_page, e_col);
    wht_cache.Cmd[0] = OLED_Fill_Pixel;
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, (uint8_t*)intput_buf, count);
}
/*全屏填充颜色,可以用来清屏*/
static void WHT_OLED_Driver_Fill_Color(uint8_t color)
{
    if (sizeof(OLED_TRx_Buf) < OLED_SCREEN_Wide)
        return;
    else
        memset(OLED_TRx_Buf, color, OLED_SCREEN_Wide);
    
	for(uint8_t Page = 0; Page < OLED_SCREEN_High / 8; Page++)
	{
        WHT_OLED_Driver_Set_Page_Window(Page, 0);
        wht_cache.Cmd[0] = OLED_Fill_Pixel;
        WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, OLED_SCREEN_Wide);
	}
}
/*提供给U8G2所使用*/
static void WHT_Write(uint8_t* input_buf, uint32_t count)
{
    wht_cache.Cmd[0] = *input_buf;
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, input_buf + 1, count - 1);
}
/************************填充*************************/


/************************字符*************************/
static void WHT_OLED_Driver_Check_Line_Feed(char intput_char)////注意字符别跨页!!!!!!!!!!
{
	if ((intput_char == '\n') || (intput_char == '\r'))
	{
		if (WHT_OLED_Info.New_Page * 8 + WHT_OLED_Info.Font->Height > OLED_SCREEN_High)
			WHT_OLED_Driver_Set_Font_Pos(0, 0);//归0
		else
		{
			WHT_OLED_Info.New_Col = 0;
			WHT_OLED_Info.New_Page += WHT_OLED_Info.Font->Height / 8;
		}
	}
}
static void WHT_OLED_Driver_Puts_ASCII(const char* intput_char)
{
    static uint8_t ASCII_Buf[64];//////当前使用的私有缓存，所以字库的选择上目前支持5*8  8*16 12*24
	static uint32_t datax = 0;
	static uint8_t* start_pos = NULL;
	
	do
	{
		if( (*intput_char < WHT_OLED_Info.Font->Start_Value) || (*intput_char > WHT_OLED_Info.Font->End_Value) )
		{
			WHT_OLED_Driver_Check_Line_Feed(*intput_char);
			return;
		}
		start_pos = &WHT_OLED_Info.Font->Buffer[(*intput_char - WHT_OLED_Info.Font->Start_Value) * WHT_OLED_Info.Font->Width_Byte * WHT_OLED_Info.Font->Height];//字符位置
		memset(ASCII_Buf, 0, sizeof(ASCII_Buf));

        for (uint8_t row = 0; row < WHT_OLED_Info.Font->Height; row++)
		{
			switch(WHT_OLED_Info.Font->Pixel_Size)
			{
			case  5 *  8:datax = start_pos[row] >> (8 - 5);break;
			case  6 * 12:datax = start_pos[row] >> (8 - 6);break;
			case  8 * 16:datax = start_pos[row] >> (8 - 8);break;
			case 12 * 24:datax = (((uint16_t*)start_pos)[row] >> 8 | ((uint16_t*)start_pos)[row] << 8) >> (16 - 12);break;
			}
			for (uint8_t col = 0; col < WHT_OLED_Info.Font->Width; col++)
			{
				if( datax & (1 << (WHT_OLED_Info.Font->Width - 1 - col)))
                {
                    if (row < 8)
                        ASCII_Buf[col + 0] |= 1 << row;
                    else if (row < 16)
                        ASCII_Buf[col + 8] |= 1 << (row - 8);
                    else if (row < 24)
                        ASCII_Buf[col + 16] |= 1 << (row - 16);
                }
			}
		}
        if (WHT_OLED_Info.Font_Color == 0)
        {
            uint16_t count = WHT_OLED_Info.Font->Height * WHT_OLED_Info.Font->Width / 8;

            for (size_t i = 0; i < count; i++)
            {
                ASCII_Buf[i] = ~ASCII_Buf[i];
            }
        }

		if(WHT_OLED_Info.New_Col + WHT_OLED_Info.Font->Width > OLED_SCREEN_Wide)
			WHT_OLED_Driver_Check_Line_Feed('\n');

        WHT_OLED_Driver_Fill_Buf(WHT_OLED_Info.New_Page, WHT_OLED_Info.New_Col, WHT_OLED_Info.New_Page + WHT_OLED_Info.Font->Height - 1, WHT_OLED_Info.New_Col + WHT_OLED_Info.Font->Width - 1, ASCII_Buf, WHT_OLED_Info.Font->Pixel_Size / 8);
		WHT_OLED_Info.New_Col += WHT_OLED_Info.Font->Width;//指针右移1个字符
		intput_char++;
	}while(*intput_char);
}
static void WHT_OLED_Driver_Clear_Row(uint8_t row)
{
	uint32_t Max_Font_Row_Count;
	
	WHT_OLED_Driver_Set_Font_Pos(row, 0);                        //设置字体位置
	Max_Font_Row_Count = OLED_SCREEN_Wide / WHT_OLED_Info.Font->Width;//获取每行最大显示字体个数
	while (Max_Font_Row_Count--)
	{
		WHT_OLED_Driver_Puts_ASCII(" ");
	}
	WHT_OLED_Driver_Set_Font_Pos(WHT_OLED_Info.New_Page, 0);          //重置指针位置
}
/************************字符*************************/


/*SSD1306寄存器配置*/
static void OLED_SSD1306_Reg_Config(void)
{
	WHT_Delay_ms(200);		// 1s,这里的延时很重要,上电后延时，没有错误的冗余设计

    wht_cache.Cmd_Count = 1;
    wht_cache.Cmd[0] = OLED_Write_Cmd;

    OLED_TRx_Buf[0] = 0xAE; //关闭显示，睡眠模式
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 1);

	OLED_TRx_Buf[0] = OLED_Set_Addressing_Mode;	//设置内存寻址模式
	OLED_TRx_Buf[1] = WHT_OLED_Addressing_Mode;
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 2);

	OLED_TRx_Buf[0] = 0xb0;	//Set Page Start Address for Page Addressing Mode,0-7
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 1);

	OLED_TRx_Buf[0] = 0xc8;	//Set COM Output Scan Direction
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 1);

	OLED_TRx_Buf[0] = 0x00; //---set low column address
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 1);

	OLED_TRx_Buf[0] = 0x10; //---set high column address
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 1);

	OLED_TRx_Buf[0] = 0x40; //--set start line address
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 1);

	OLED_TRx_Buf[0] = 0x81; //设置对比度控制寄存器
	OLED_TRx_Buf[1] = WHT_OLED_Info.LM;
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 2);

	OLED_TRx_Buf[0] = 0xa1; //--set segment re-map 0 to 127
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 1);

	OLED_TRx_Buf[0] = 0xa6; //--set normal display
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 1);

	OLED_TRx_Buf[0] = 0xa8; //--set multiplex ratio(1 to 64)
	OLED_TRx_Buf[1] = 0x3F; //
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 2);

	OLED_TRx_Buf[0] = 0xa4; //0xa4,Output follows RAM content;0xa5,Output ignores RAM content
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 1);

	OLED_TRx_Buf[0] = 0xd3; //-set display offset
	OLED_TRx_Buf[1] = 0x00; //-not offset
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 2);

	OLED_TRx_Buf[0] = 0xd5; //--set display clock divide ratio/oscillator frequency
	OLED_TRx_Buf[1] = 0xf0; //--set divide ratio
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 2);

	OLED_TRx_Buf[0] = 0xd9; //--set pre-charge period
	OLED_TRx_Buf[1] = 0x22; //
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 2);

	OLED_TRx_Buf[0] = 0xda; //--set com pins hardware configuration
	OLED_TRx_Buf[1] = 0x12;
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 2);

	OLED_TRx_Buf[0] = 0xdb; //--set vcomh
	OLED_TRx_Buf[1] = 0x10; //0x00 0.65*Vcc,0x10 0.77*Vcc,0x30 0.83*Vcc
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 2);

	OLED_TRx_Buf[0] = 0x8d; //--set DC-DC enable
	OLED_TRx_Buf[1] = 0x14; //
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 2);

	OLED_TRx_Buf[0] = 0xaf; //打开显示，正常模式
    WHT_OLED_Driver_Write(OLED_7Bit_Addr0, OLED_TRx_Buf, 1);
}

static void WHT_OLED_Init(void)
{
    WHT_OLED_Info.LM = 255;
	*(uint16_t*)&WHT_OLED_Info.X_Length = OLED_SCREEN_Wide;
	*(uint16_t*)&WHT_OLED_Info.Y_Length = OLED_SCREEN_High;
	WHT_OLED_Info.Font = (WHT_Font_Info_t*)&Font_ASCII_5x8;
	WHT_OLED_Info.New_Col = 0;
	WHT_OLED_Info.New_Page = 0;
	WHT_OLED_Info.BK_Color = 0;
	WHT_OLED_Info.Font_Color = 1;

    WHT_OLED_Driver_Init();
    OLED_SSD1306_Reg_Config();
    WHT_OLED_Driver_Fill_Color(0x00);
}

const WHT_OLED_Driver_t WHT_OLED_Driver =
{
    .WHT_OLED_Info            = &WHT_OLED_Info,
    .WHT_Send_Buf             = OLED_TRx_Buf,
    .WHT_Scan_I2C_Slave_Count = WHT_OLED_Driver_Scan_I2C_Slave_Count,
    .WHT_OLED_Init            = WHT_OLED_Init,
    .WHT_Set_Font_Pos         = WHT_OLED_Driver_Set_Font_Pos,
    .WHT_Set_LM               = WHT_OLED_Driver_Set_LM,
    .WHT_Clear_Row            = WHT_OLED_Driver_Clear_Row,
    .WHT_Puts                 = WHT_OLED_Driver_Puts_ASCII,
    .WHT_Write                = WHT_Write,
};

void OLED_TEST_FUNC(void)
{
    WHT_OLED_Driver.WHT_OLED_Init();

	WHT_OLED_Driver_Fill_Color(0x00);//清屏
    WHT_Delay_ms(500);

    memset(OLED_TRx_Buf, 0xff, 1024);
    WHT_OLED_Driver_Fill_Buf(0, 0, 7, 127, OLED_TRx_Buf, 1024);
    WHT_Delay_ms(500);

    memset(OLED_TRx_Buf, 0, 1024);
    WHT_OLED_Driver_Fill_Buf(0, 0, 7, 127, OLED_TRx_Buf, 1024);
    WHT_Delay_ms(500);

    WHT_OLED_Info.Font = (WHT_Font_Info_t*)&Font_ASCII_8x16;
    WHT_OLED_Driver_Set_Font_Pos(0,30);
    WHT_OLED_Driver_Puts_ASCII("hello word");
    WHT_Delay_ms(500);
    
    uint8_t row = 0;
    WHT_OLED_Info.Font = (WHT_Font_Info_t*)&Font_ASCII_5x8;
    WHT_OLED_Driver_Fill_Color(0x00);//清屏
	while(1)
	{
        if (++row == 8)
        {
            row = 0;
        }
        WHT_OLED_Driver_Set_Font_Pos(row, 30);
        WHT_OLED_Driver_Puts_ASCII("Hello Word ABC");
        vTaskDelay(15);
        WHT_OLED_Driver_Clear_Row(row);
        break;
	}
}
